#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <limits>
#include <stdexcept>

struct Record
{
    int id;
    std::string data;
    Record(int i, const std::string &d) : id(i), data(d) {}
};

struct Table
{
    std::string name;
    std::vector<Record> records;
    Table(const std::string &n) : name(n) {}
};

class SimpleDB
{
private:
    std::vector<Table> tables;
    std::string data_file = "simple_db.dat";

    void saveToFile()
    {
        std::ofstream file(data_file, std::ios::binary);
        if (!file.is_open())
        {
            std::cerr << "无法打开文件进行保存" << std::endl;
            return;
        }

        // 写入表数量
        size_t table_count = tables.size();
        file.write(reinterpret_cast<const char *>(&table_count), sizeof(table_count));

        // 写入每个表
        for (const auto &table : tables)
        {
            // 表名
            size_t name_size = table.name.size();
            file.write(reinterpret_cast<const char *>(&name_size), sizeof(name_size));
            file.write(table.name.c_str(), name_size);

            // 记录数量
            size_t record_count = table.records.size();
            file.write(reinterpret_cast<const char *>(&record_count), sizeof(record_count));

            // 写入每条记录
            for (const auto &record : table.records)
            {
                file.write(reinterpret_cast<const char *>(&record.id), sizeof(record.id));

                size_t data_size = record.data.size();
                file.write(reinterpret_cast<const char *>(&data_size), sizeof(data_size));
                file.write(record.data.c_str(), data_size);
            }
        }

        file.close();
        std::cout << "数据已保存到文件" << std::endl;
    }

    void loadFromFile()
    {
        std::ifstream file(data_file, std::ios::binary);
        if (!file.is_open())
        {
            std::cout << "没有找到之前的数据库文件，创建新的数据库" << std::endl;
            return;
        }

        tables.clear();

        // 读取表数量
        size_t table_count;
        file.read(reinterpret_cast<char *>(&table_count), sizeof(table_count));

        // 读取每个表
        for (size_t i = 0; i < table_count; ++i)
        {
            // 读取表名
            size_t name_size;
            file.read(reinterpret_cast<char *>(&name_size), sizeof(name_size));
            std::string table_name(name_size, '\0');
            file.read(&table_name[0], name_size);

            Table table(table_name);

            // 读取记录数量
            size_t record_count;
            file.read(reinterpret_cast<char *>(&record_count), sizeof(record_count));

            // 读取每条记录
            for (size_t j = 0; j < record_count; ++j)
            {
                int id;
                file.read(reinterpret_cast<char *>(&id), sizeof(id));

                size_t data_size;
                file.read(reinterpret_cast<char *>(&data_size), sizeof(data_size));
                std::string data(data_size, '\0');
                file.read(&data[0], data_size);

                table.records.push_back(Record(id, data));
            }

            tables.push_back(table);
        }

        file.close();
        std::cout << "数据已从文件加载" << std::endl;
    }

public:
    SimpleDB()
    {
        loadFromFile();
    }

    ~SimpleDB()
    {
        saveToFile();
    }

    void createTable(const std::string &name)
    {
        for (const auto &table : tables)
        {
            if (table.name == name)
            {
                std::cout << "表 '" << name << "' 已存在" << std::endl;
                return;
            }
        }
        tables.push_back(Table(name));
        std::cout << "表 '" << name << "' 创建成功" << std::endl;
    }

    void insertRecord(const std::string &tableName, int id, const std::string &data)
    {
        for (auto &table : tables)
        {
            if (table.name == tableName)
            {
                table.records.push_back(Record(id, data));
                std::cout << "记录插入成功: ID=" << id << ", Data='" << data << "'" << std::endl;
                return;
            }
        }
        std::cout << "表 '" << tableName << "' 不存在" << std::endl;
    }

    void showRecords(const std::string &tableName)
    {
        for (const auto &table : tables)
        {
            if (table.name == tableName)
            {
                std::cout << "表 '" << tableName << "' 的记录:" << std::endl;
                for (size_t i = 0; i < table.records.size(); ++i)
                {
                    const auto &record = table.records[i];
                    std::cout << "  " << (i + 1) << ". ID: " << record.id
                              << ", Data: " << record.data << std::endl;
                }
                return;
            }
        }
        std::cout << "表 '" << tableName << "' 不存在" << std::endl;
    }

    void showTables()
    {
        std::cout << "数据库中的表:" << std::endl;
        if (tables.empty())
        {
            std::cout << "  (暂无表)" << std::endl;
            return;
        }

        for (size_t i = 0; i < tables.size(); ++i)
        {
            const auto &table = tables[i];
            std::cout << "  " << (i + 1) << ". " << table.name
                      << " (记录数: " << table.records.size() << ")" << std::endl;
        }
    }
};

void printMenu()
{
    std::cout << "\n====================" << std::endl;
    std::cout << "简单数据库系统 (支持持久化)" << std::endl;
    std::cout << "====================" << std::endl;
    std::cout << "1. 显示所有表" << std::endl;
    std::cout << "2. 创建表" << std::endl;
    std::cout << "3. 插入记录" << std::endl;
    std::cout << "4. 显示记录" << std::endl;
    std::cout << "0. 退出" << std::endl;
    std::cout << "====================" << std::endl;
    std::cout << "选择操作: ";
}

int main()
{
    std::cout << "🚀 简单数据库系统启动" << std::endl;
    std::cout << "📁 数据将自动保存到 simple_db.dat 文件" << std::endl;
    std::cout << "🔄 下次启动时会自动加载之前的数据" << std::endl;

    SimpleDB db;
    int choice;

    do
    {
        printMenu();
        std::cin >> choice;

        switch (choice)
        {
        case 1:
            db.showTables();
            break;
        case 2:
        {
            std::string table_name;
            // 清除输入缓冲区
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "输入表名: ";
            std::getline(std::cin, table_name);
            db.createTable(table_name);
            break;
        }
        case 3:
        {
            std::string table_name;
            int id;
            std::string data;

            // 清除输入缓冲区
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

            std::cout << "输入表名: ";
            std::getline(std::cin, table_name);

            std::cout << "输入记录ID: ";
            std::string id_str;
            std::getline(std::cin, id_str);

            // 转换字符串到整数
            try
            {
                id = std::stoi(id_str);
            }
            catch (const std::exception &)
            {
                std::cout << "无效的ID格式，请输入数字" << std::endl;
                break;
            }

            std::cout << "输入记录数据: ";
            std::getline(std::cin, data);

            db.insertRecord(table_name, id, data);
            break;
        }
        case 4:
        {
            std::string table_name;
            // 清除输入缓冲区
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "输入表名: ";
            std::getline(std::cin, table_name);
            db.showRecords(table_name);
            break;
        }
        case 0:
            std::cout << "\n👋 感谢使用！数据已自动保存。" << std::endl;
            break;
        default:
            std::cout << "无效选择，请重新输入" << std::endl;
        }

        if (choice != 0)
        {
            std::cout << "\n按回车键继续...";
            std::cin.ignore();
            std::cin.get();
        }

    } while (choice != 0);

    return 0;
}
